package com.hm.myrecyclervview

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MyDecoration(context: Context) : RecyclerView.ItemDecoration() {

    private var headPaint: Paint? = null

    private var textPaint: Paint? = null

    private var headHight: Int = 0

    init {
        headPaint = Paint()
        headPaint?.color = Color.rgb(0, 255, 0)
        textPaint = Paint()
        textPaint?.strokeWidth = 0.01f

        textPaint?.style = Paint.Style.FILL

        textPaint?.color = Color.rgb(0, 0, 255)
        headHight = dp2px(context, 100F)
        textPaint?.textSize = headHight.toFloat()

    }

    /**
     * 1.先把每个item的之间的间距计算出来
     * 自定义getItemOffsets函数
     * 该函数用于计算每个item的偏移量，以实现特定的布局效果
     * 在这个函数中，我们主要关注的是设置每个item的上边距，根据item是否是组头来决定边距的大小
     *
     * @param outRect 用于记录每个item的偏移量的矩形对象
     * @param view 当前正在处理的item视图
     * @param parent RecyclerView对象，用于访问适配器和其他RecyclerView相关的信息
     * @param state RecyclerView的状态对象，包含有关当前RecyclerView布局状态的信息
     */
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State,
    ) {
        super.getItemOffsets(outRect, view, parent, state)

        // 检查当前RecyclerView的适配器是否为MyAdapter类型
        if (parent.adapter is MyAdapter) {

            // 将适配器转换为MyAdapter类型以便于后续操作
            var myadapte: MyAdapter = parent.adapter as MyAdapter
            // 获取当前item在适配器中的位置
            val childAdapterPosition = parent.getChildAdapterPosition(view)

            // 判断当前item是否是组头
            val gourpHeader = myadapte.isGourpHeader(childAdapterPosition)

            // 根据是否是组头来设置item的上边距
            if (gourpHeader) {
                outRect.top = headHight
            } else {
                outRect.top = 5
            }
        }
    }

    /**
     * 2.将第一步计算出来的间隔绘制相依的显示内容
     */
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        // 调用父类的onDraw方法以处理默认绘制逻辑
        super.onDraw(c, parent, state)

        // 仅当RecyclerView的适配器是MyAdapter类型时执行自定义绘制逻辑
        if (parent.adapter is MyAdapter) {

            // 定义绘制区域的左边界和右边界
            val Left = parent.paddingLeft
            val Right = parent.width - parent.paddingRight
            // 设置头部绘制的颜色为绿色
            headPaint?.color = Color.rgb(0, 255, 0)

            // 强制转换适配器为MyAdapter类型以访问其特定方法
            val madapter = parent.adapter as MyAdapter
            // 遍历RecyclerView的所有子视图
            for (i in 0 until parent.childCount) {

                // 获取当前子视图和其在适配器中的位置
                val childAtView = parent.getChildAt(i)
                val childAdapterPosition = parent.getChildAdapterPosition(childAtView)

                // 使用Rect定义裁剪区域
                val clipRect = RectF(
                    Left.toFloat(),
                    parent.paddingTop.toFloat(),
                    Right.toFloat(),
                    parent.height.toFloat()
                )
                // 从(100,100)到(500,500)的矩形区域
                c.clipRect(clipRect)
                // 检查当前项是否为组头
                if (madapter.isGourpHeader(childAdapterPosition)) {

                    // 绘制组头背景
                    c.drawRect(
                        Left.toFloat(),
                        (childAtView.top - headHight).toFloat(), Right.toFloat(),
                        childAtView.top.toFloat(), headPaint!!
                    )

                    // 获取文本绘制的基线位置
                    val fontMetrics: Paint.FontMetrics = textPaint!!.fontMetrics
                    val baseline: Float =
                        headHight.toFloat() / 2 + (fontMetrics.descent + fontMetrics.ascent) / 2

                    // 绘制组名文本
                    c.drawText(
                        madapter.getGroupName(childAdapterPosition), Left.toFloat(),
                        childAtView.top.toFloat() - baseline, textPaint!!
                    )

                } else {
                    // 绘制非组头项的背景
                    c.drawRect(
                        Left.toFloat(),
                        (childAtView.top - 5).toFloat(), Right.toFloat(),
                        childAtView.top.toFloat(), headPaint!!
                    )
                }
            }
        }
    }

    /**
     * 3.在RecyclerView顶部绘制一块儿view用于达到可以上移缩放的目的。
     * 在RecyclerView上绘制额外的装饰性内容。
     * 此方法主要用于在RecyclerView及其子视图上绘制额外的图形或文本，以提供更丰富的用户体验。
     *
     * @param c 用于绘制的画布。
     * @param parent RecyclerView实例，用于访问适配器、布局管理器等。
     * @param state RecyclerView的当前状态，包含正在显示的条目信息。
     */
    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(c, parent, state)
        if (parent.adapter is MyAdapter) {
            // 获取RecyclerView的左边、右边和上边的位置
            val left = parent.paddingLeft
            val right = parent.width - parent.paddingRight
            val top = parent.paddingTop

            // 将parent.adapter转换为MyAdapter类型，以便调用其特定方法
            val myAdapter = parent.adapter as MyAdapter
            // 返回可见区域内的第一个item的position
            val position =
                (parent.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()

            // 获取当前项的视图
            val itemview = parent.findViewHolderForAdapterPosition(position)?.itemView
            // 获取文本画笔的字体指标，用于计算基线位置
            val fontMetrics: Paint.FontMetrics = textPaint!!.fontMetrics

            // 计算文本基线的位置
            val baseline: Float =
                headHight.toFloat() / 2 + (fontMetrics.descent + fontMetrics.ascent) / 2
            // 判断下一个位置是否是组头
            if (myAdapter.isGourpHeader(position + 1)) {
                // 计算矩形的底部边界
                val bottom = Math.min(
                    (top + headHight).toFloat(),
                    itemview?.bottom?.toFloat() ?: (top + headHight).toFloat()
                )

                // 绘制矩形背景
                c.drawRect(
                    left.toFloat(), top.toFloat(), right.toFloat(), bottom,
                    headPaint!!
                )
                // 在矩形内绘制组名
                c.drawText(
                    myAdapter.getGroupName(position), left.toFloat(),
                     bottom - baseline, textPaint!!
                )
            } else {
                // 如果不是组头，绘制不同的矩形背景
                c.drawRect(
                    left.toFloat(), top.toFloat(), right.toFloat(), (top + headHight).toFloat(),
                    headPaint!!
                )

                // 在矩形内绘制组名
                c.drawText(
                    myAdapter.getGroupName(position), left.toFloat(),
                    top.toFloat() + headHight - baseline, textPaint!!
                )
            }
        }
    }


    /**
     * 将dp值转换为px值
     *
     * @param context 上下文对象，用于获取显示指标
     * @param dpValue 需要转换的dp值
     * @return 转换后的px值
     */
    private fun dp2px(context: Context, dpValue: Float): Int {
        // 获取屏幕密度
        val scale = context.resources.displayMetrics.density
        // 将dp值乘以屏幕密度，并四舍五入
        return (dpValue * scale * 0.5f).toInt()
    }


}